#include<vector>
#include<unordered_set>
using namespace std;
class Solution {
private:
    int findParent(const vector<int>& parents, int index) {
        if (parents[index] == -1) return index;
        return findParent(parents, parents[index]);
    }
    void unionFind(vector<int>& parents, int index1, int index2) {
        int tmp1 = findParent(parents, index1);
        int tmp2 = findParent(parents, index2);
        if (tmp1 != tmp2)
            parents[tmp2] = tmp1;
    }
public:
    int removeStones(vector<vector<int>>& stones) {
        if (stones.size() < 2)
            return 0;
        int rows = 0;
        int cols = 0;
        for (auto& stone : stones) {
            rows = rows > stone[0] ? rows : stone[0];
            cols = cols > stone[1] ? cols : stone[1];
        }
        ++rows;
        ++cols;
        vector<int>parents(rows+cols, -1);
        for (auto& stone : stones) {
            unionFind(parents, stone[0], stone[1] + rows);
        }
        unordered_set<int>set_;
        for (auto& stone : stones) {
            if (findParent(parents, stone[0]) == stone[0]) 
                set_.insert(stone[0]);
            else if (findParent(parents, stone[1] + rows) == stone[1] + rows)
                set_.insert(stone[1] + rows);
        }
        return stones.size() - set_.size();
    }
};

//int main() {
//    vector<vector<int>> stones;
//    stones.push_back({ 0,0 });
//    stones.push_back({ 0,1 });
//    stones.push_back({ 1,0 });
//    stones.push_back({ 1,2 });
//    stones.push_back({ 2,1 });
//    stones.push_back({ 2,2 });
//    Solution sol;
//    sol.removeStones(stones);
//}